package sub2;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.TimerTask;

/**
 * Handle a client crash
 * Regularly send a ping to each registered client
 * @see Server
 * @author Magali Moulin, Pierre Labiausse
 * @version 2
 */
public class SendPings extends TimerTask {
	private Server server;
	private Directory directory;
	
	/**
	 * Constructor 
	 * @param server
	 * @param directory
	 */
	public SendPings(Server server,Directory directory){
		this.server = server;
		this.directory=directory;
	}
	
	/**
	 * Create a thread SendPing for each client on the list of registered clients 
	 */
	public void run(){
		for(ClientTcpTuple peer : directory.listPeer()){
			(new SendPing(peer, server,directory)).start();
		}
		
	}
}

/**
 * Handle a client crash
 * Thread which ping periodically a list of registered clients and removes directory entries that correspond to unreachable clients
 * @author Magali Moulin, Pierre Labiausse
 * @version 2
 */
class SendPing extends Thread {
	private ClientTcpTuple peer;
	private Server server;
	private Directory directory;
	
	/**
	 * Constructor of this class which takes in parameters a clientTcpTuple and the server
	 * @param tuple
	 * @param server
	 * @param directory
	 */
	public SendPing(ClientTcpTuple peer, Server server, Directory directory){
		this.peer = peer;
		this.server = server;
		this.directory=directory;
	}
	
	/**
	 * Action of the thread: ping periodically a list of registered clients and removes directory entries that correspond to unreachable clients
	 */
	public void run(){
		try {
			Socket socket = new Socket(peer.getInetAddress(), peer.getPort());
			PrintWriter out = new PrintWriter(socket.getOutputStream());
			out.println("ping");
			out.flush();
			ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
			String response = (String) in.readObject();
			if(!response.equals("pong")){
				System.out.println("Removing "+peer.getInetAddress()+":"+peer.getPort());
				directory.deletePeer(peer.getInetAddress().getHostAddress(), peer.getPort());
			}
			in.close();
			out.close();
			socket.close();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println("Removing "+peer.getInetAddress()+":"+peer.getPort());
			directory.deletePeer(peer.getInetAddress().getHostAddress(), peer.getPort());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}
